package cn.madog.ui;

import cn.madog.utils.HandleDoc;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.image.Image;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Paint;
import javafx.scene.text.Text;
import javafx.scene.text.TextAlignment;
import javafx.stage.DirectoryChooser;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Main extends Application {

    private BorderPane root;

    public static void main(String[] args) {
        launch(args);
    }

    private Stage stage;

    private ObservableList<FileBean> fileBeans = FXCollections.observableArrayList();

    private File saveDirectory;

    private ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3, 8, 5, TimeUnit.SECONDS, new LinkedBlockingDeque<>());

    @Override
    public void start(Stage primaryStage) throws IOException {

        stage = primaryStage;
        root = new BorderPane();
        Scene scene = new Scene(root, 800, 600);

        primaryStage.setMinHeight(600);
        primaryStage.setMinWidth(800);

        primaryStage.getIcons().add(new Image("image/ic_launcher_round.png"));

        primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
            @Override
            public void handle(WindowEvent event) {
                System.exit(0);
            }
        });

        initHeaderView();

        initTabContent();

        initBottomView();

        primaryStage.setScene(scene);

        primaryStage.show();

    }


    // 开始之后 不可进行其他操作
    private Boolean starting = false;
    // 是否完成，可下载
    private Boolean isComplete = false;

    private void initBottomView() {
        Pane saveLocation = initSaveLocation();
        Pane buttonView = initBottomButtonView();
        VBox vBox = new VBox(10, saveLocation, buttonView);
        root.setBottom(vBox);
    }

    private Pane initSaveLocation() {

        TextField locationLabel = new TextField();
        locationLabel.setEditable(false);

        locationLabel.setPrefSize(680, 30);

        Button btnSelect = new Button("选择保存路径");
        btnSelect.setPrefSize(120, 30);
        btnSelect.setOnMouseClicked(event -> {
            if (starting) {
                new Alert(Alert.AlertType.INFORMATION, "开始处理之后不可修改储存路径").showAndWait();
                return;
            }

            DirectoryChooser directoryChooser = new DirectoryChooser();
            directoryChooser.setTitle("请选择保存到哪个目录");

            File file = directoryChooser.showDialog(stage);
            if (file != null) {
                saveDirectory = file;
            }

            if (saveDirectory != null) {
                locationLabel.setText(saveDirectory.getPath());
            }
        });

        HBox hBox = new HBox(10, locationLabel, btnSelect);
        hBox.setPadding(new Insets(10, 10, 0, 10));
        return hBox;
    }

    private Pane initBottomButtonView() {

        BorderPane bBorderPane = new BorderPane();

        Button selectButton = initSelectButton();

        Button startButton = initStartButton();

        bBorderPane.setLeft(selectButton);
        bBorderPane.setRight(startButton);
        bBorderPane.setPadding(new Insets(10, 10, 10, 10));

        return bBorderPane;
    }

    private Button initStartButton() {
        Button start = new Button("开始");
        setButtonProperty(start);
        start.setOnMouseClicked(event -> {
            if (fileBeans.isEmpty()) {
                new Alert(Alert.AlertType.INFORMATION, "还没有选择文件").show();
                return;
            }
            if (saveDirectory == null || !saveDirectory.exists() || !saveDirectory.canWrite()) {
                new Alert(Alert.AlertType.INFORMATION, "该文件夹不能保存，请换一个保存路径试试").show();
                return;
            }

            if (starting) {
                new Alert(Alert.AlertType.INFORMATION, "正在处理中").showAndWait();
                return;
            }

            fileBeans.forEach(this::startHandleQuestion);
            starting = true;

            ListenerThreadEnd();

        });
        return start;
    }

    private void ListenerThreadEnd() {

        new Thread(() -> {
            while (true) {
                try {

                    if (threadPoolExecutor.getCompletedTaskCount() == threadPoolExecutor.getTaskCount()) {

                        // 所有线程执行完成
                        starting = false;
                        isComplete = true;

                        System.out.println("Main.ListenerThreadEnd");

                        Platform.runLater(() -> {
                            new Alert(Alert.AlertType.INFORMATION, "完成").show();
                        });

                        break;
                    }

                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }


    private void startHandleQuestion(FileBean fileBean) {
        Runnable runnable = initRunnable(fileBean);

        threadPoolExecutor.execute(runnable);
    }

    private Runnable initRunnable(FileBean fileBean) {
        return () -> {
            System.out.println(">>>>>>>>>> 准备开始处理 " + fileBean.nameProperty() + " 文件内容 <<<<<<<<<<<");

            HandleDoc handleDoc = new HandleDoc();
            handleDoc.handleFile(fileBean, saveDirectory);
        };
    }

    private Button initDownloadButton() {
        Button download = new Button("下载");
        setButtonProperty(download);
        download.setOnMouseClicked(event -> {
            if (!isComplete) {
                new Alert(Alert.AlertType.INFORMATION, "没有已完成的处理任务").showAndWait();
                return;
            }

        });
        return download;
    }

    private void setButtonProperty(Button start) {
        start.setPrefSize(160, 60);
        start.setTextAlignment(TextAlignment.CENTER);
        start.setStyle("-fx-background-insets: 0");
    }

    private Button initSelectButton() {
        Button select = new Button("选择文件");
        setButtonProperty(select);
        select.setOnMouseClicked(event -> {
            if (starting) {
                new Alert(Alert.AlertType.INFORMATION, "正在处理中").showAndWait();
                return;
            }

            FileChooser fileChooser = new FileChooser();
            fileChooser.setTitle("选择excel文件");
            fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("doc", "*.doc", "*.docx"));
            List<File> files = fileChooser.showOpenMultipleDialog(stage);

            if (files != null) {
                handleFiles(files);
            }
        });

        return select;
    }

    private void initTabContent() {

        TableView<FileBean> tableView = new TableView<>(fileBeans);

        TableColumn<FileBean, String> tableColumnName = new TableColumn<>("名称");
        tableColumnName.setSortable(false);
        tableColumnName.setCellValueFactory(param -> param.getValue().nameProperty());

        tableColumnName.setPrefWidth(320);

        TableColumn<FileBean, String> tableColumnStatus = new TableColumn<>("状态");
        tableColumnStatus.setSortable(true);
        tableColumnStatus.setCellValueFactory(param -> param.getValue().statusStrProperty());

        TableColumn<FileBean, String> tableColumnMsg = new TableColumn<>("备注");
        tableColumnMsg.setSortable(false);
        tableColumnMsg.setCellValueFactory(param -> param.getValue().msgProperty());

        tableColumnStatus.setPrefWidth(80);
        tableColumnMsg.setPrefWidth(390);

        tableColumnMsg.setCellFactory(TextFieldTableCell.forTableColumn());

        tableView.getColumns().add(tableColumnName);
        tableView.getColumns().add(tableColumnMsg);
        tableView.getColumns().add(tableColumnStatus);

        tableView.setStyle("-fx-background-insets: 0");
        tableView.setEditable(true);

        root.setCenter(tableView);

    }

    private void initHeaderView() {

        BorderPane hBorderPane = new BorderPane();
        hBorderPane.setStyle("-fx-background-color: WHITE;");

        Text text = new Text(
                "1、选择文件必须是word文件\n" +
                        "2、文件第一行必须标明题类型,必须一致，注意大小写 \n\n" +
                        "类型:A1型题、A2型题、A3/A4型题、B1型题");
        text.setTextAlignment(TextAlignment.LEFT);
        text.setFill(Paint.valueOf("#888888"));
        hBorderPane.setCenter(text);
        hBorderPane.setPadding(new Insets(20, 0, 20, 0));

        root.setTop(hBorderPane);
    }

    private void handleFiles(List<File> files) {

        fileBeans.clear();

        files.forEach(file -> {
            fileBeans.add(new FileBean(file, file.getName(), -1));
        });

    }

}
